#include "game.h"
#include "Robot.h"
#include "ASprite.h"
#include "Font.h"
#include "Box2D.h"

Robot::Robot()
{
	SetObjectType(Object_Robot);	
	m_sprite = GetResManager()->getSprite(SPRITE_CHARACTER);
	DisableMovement();
	m_radiusHead = 32;
	SetObjectType(Object_Robot);	
	m_speedUnit = 0.5f;
	m_Speed = vector2df(0.5f,0);
	EnableMovement();
	m_bMoved = false;
}

void Robot::SaveData(CWriteFile* stream)
{
	GameObject::SaveData(stream);

	stream->WriteS32(m_targetPoint.X);
	stream->WriteS32(m_targetPoint.Y);

	stream->WriteF32(m_Speed.X);
	stream->WriteF32(m_Speed.Y);
	stream->WriteF32(m_displacement.X);
	stream->WriteF32(m_displacement.Y);

	stream->WriteS8(m_bIsMovementEnabled);

	stream->WriteS32(m_radiusHead);
	stream->WriteS32(m_hp);
}
void Robot::LoadData(CReadFile* stream)
{
	GameObject::LoadData(stream);

	m_targetPoint.X = stream->ReadS32();
	m_targetPoint.Y = stream->ReadS32();

	m_Speed.X = stream->ReadF32();
	m_Speed.Y = stream->ReadF32();
	m_displacement.X = stream->ReadF32();
	m_displacement.Y = stream->ReadF32();

	m_bIsMovementEnabled = stream->ReadS8();
	m_radiusHead = stream->ReadS32();
	m_hp = stream->ReadS32();

}

void Robot::InitPhysics()
{
	IReadFile* file = getFileSystem()->createAndOpenFile("data/abc.bln");
	{
		b2BodyDef bodyDef;
		bodyDef.position.x = 8;
		bodyDef.position.y = 0.1f;
		bodyDef.angle = 0;//m_boundingVolume.GetOrientation().z;
		ASSERT( !m_physicsBody );
		m_physicsBody = GetGameObjectManager()->GetPhysicsWorld().CreateBody( &bodyDef );
		ASSERT( m_physicsBody );
		if ( m_physicsBody )
		{
			int numShape = file->ReadS32();
			for(int i =0;i<numShape;i++)
			{
				b2PolygonDef shapeDef;
				shapeDef.vertexCount = file->ReadS32();

				for(int j =0;j<shapeDef.vertexCount;j++)
				{
					shapeDef.vertices[j].Set(file->ReadF32(),file->ReadF32());
				}

				shapeDef.density = 1.0f;
				shapeDef.friction = 0.3f;
				//shapeDef.filter.categoryBits = 0x0004;

				m_physicsBody->CreateShape( &shapeDef );
				m_physicsBody->SetMassFromShapes();
			}


			
			
			m_physicsBody->SetUserData( this );	
		}
	}
	//b2BodyDef bodyDef;
	//bodyDef.position.x = m_boundingbox->GetCenterX();
	//bodyDef.position.y = m_boundingbox->GetCenterY();
	//bodyDef.angle = 0;//m_boundingVolume.GetOrientation().z;

	//b2PolygonDef shapeDef;
	//shapeDef.SetAsBox( m_boundingbox->GetWidth()/2, m_boundingbox->GetHeight()/2 );
	//
	//shapeDef.density = 1;
	//shapeDef.friction = 0;//0.3f;
	//
	//shapeDef.restitution = 0.5f;

	//shapeDef.filter.categoryBits = ( 1 << 1 ) ;

	//ASSERT( !m_physicsBody );
	//m_physicsBody = GetGameObjectManager()->GetPhysicsWorld().CreateBody( &bodyDef );
	//ASSERT( m_physicsBody );
	//if ( m_physicsBody )
	//{
	//	m_physicsBody->CreateShape( &shapeDef );
	//	m_physicsBody->SetMassFromShapes();

	//	m_physicsBody->SetUserData( this );
	//}
}

void Robot::Load(IAttributes* attr)
{	

	m_hp = attr->getAttributeAsInt("HP");
	//m_position.set(attr->getAttributeAsInt("X"),attr->getAttributeAsInt("Y"));

	m_TimeReload = attr->getAttributeAsInt("TimeReload");
	m_status.m_TimeCountdown = m_TimeReload/4;

	SetEnabled(attr->getAttributeAsBool("Enabled"));

}

void Robot::SetTarget(float tx,float ty)
{
	m_targetPoint = vector2df(tx, ty);
	m_Speed = m_speedUnit * (m_targetPoint - vector2df(m_physicsBody->GetPosition().x,m_physicsBody->GetPosition().y)).normalize();
	m_bMoved = false;
}

void Robot::TakeDamage(int damage)
{
	m_hp -= damage*50/100;
	if(m_hp <=0)
	{
		m_hp = 0;
		SetEnabled(false);
		getGame()->SignalRobotDead();
	}
}

void Robot::Draw()
{
	

	/*int headPad = 80;
	int chestPad = 32;
	int backPad = 32;*/
	
	//getGfx()->DrawCircle2(m_position.X,m_position.Y - headPad,m_radiusHead);			

	//getGfx()->DrawLine(m_position.X - chestPad,m_position.Y  - headPad,
	//	m_position.X - chestPad,m_position.Y);
	//getGfx()->DrawLine(m_position.X + backPad,m_position.Y  - headPad,
	//	m_position.X + backPad,m_position.Y);
#if (SHOW_BOUND_RECT)
	getGfx()->SetColor(0xff00ff00);	
	getGfx()->DrawRect(m_boundingbox->left,
		m_boundingbox->top,
		m_boundingbox->GetWidth(),
		m_boundingbox->GetHeight());
#endif
	/*getGfx()->SetColor(0xffff0000);	
	for(int i =0;i<m_boundinglines.size();i++)
	{
		getGfx()->DrawLine(m_position.X + m_boundinglines[i].start.X,m_position.Y  + m_boundinglines[i].start.Y,
						   m_position.X + m_boundinglines[i].end.X,m_position.Y  + m_boundinglines[i].end.Y);
	}

	*/

	char buff[32];
	sprintf(buff,"HP:%d",m_hp);
	getFont()->DrawText2((GL_TCHAR*)buff,m_physicsBody->GetPosition().x,m_physicsBody->GetPosition().y);
	m_sprite->PaintFrame(0,m_physicsBody->GetPosition().x,m_physicsBody->GetPosition().y);

		
}

void Robot::Update()
{
	GameObject::Update();
	/*if(GetPosition().X < 120)
		SetEnabled(false);*/
	m_cooldownTimer.Update(getGame()->GetGameplayTimeStep());
	if(m_cooldownTimer.IsDone())
	{
		ThrowableObj* thowObj = (ThrowableObj*)GetGameObjectManager()->Spawn("Bullet");
		thowObj->SetPosition(m_physicsBody->GetPosition().x,m_physicsBody->GetPosition().y);
		thowObj->SetSpeed(b2Vec2(-5.0f,5.0f));
		m_cooldownTimer.SetTime(5);
	}
}

void Robot::reset()
{
	m_hp = 100;

	m_TimeReload = 8;
	m_status.m_TimeCountdown = 2;
}

void Robot::Initialize()
{	

	//InitPhysics();
	m_cooldownTimer.SetTime(2);
	m_cooldownTimer.SetEnable(false);
	
}

bool Robot::ShouldCollideWith( GameObject* h ) 
{
	if(h->GetObjectType() == Object_Robot ||
		h->GetObjectType() == Object_ThrowableObj)
		return false;
	return true; 
}
void Robot::Update_PreCollision()
{
	if(CanMove())
	{ 		
		CompDisplacement();
	}
}
void Robot::Update_PostCollision()
{
	if ( ! m_physicsBody )
	{
		return;
	}

	if(!m_bMoved)
	{
		if(m_physicsBody->GetPosition().x<m_targetPoint.X)	
		//if(m_physicsBody->GetPosition().x<5)
		{
			m_bMoved = true;
			m_cooldownTimer.SetEnable(true);
			DisableMovement();
		}
	}
	else
	{

	}
	/*if(!m_bMoved)
	{
		ResolveCollisions();

		SetPosition(GetPosition() + m_displacement);

		if(m_position == m_targetPoint)
		{
			m_bMoved = true;
			DisableMovement();
		}
		
		ReCalBoundingBox();
	}
	else
	{
		m_status.m_TimeCountdown -= TIME_STEP/1000.0f;
		if(m_status.m_TimeCountdown <=0)
		{
			m_status.m_TimeCountdown = m_TimeReload;
			ThrowableObj* throwObj = GetRobotFactory()->getFreeThrowableObj(0);

			if(throwObj)
			{
				throwObj->SetEnabled(true);
				throwObj->Throw(m_position.X,m_position.Y,-10,-15);										
			}

		}
	}*/
}
//void Robot::ResolveCollisions()
//{
//
//	vector2df newpos = GetPosition() + m_displacement;
//	if(!newpos.isBetweenPoints(m_targetPoint,m_position))
//	{
//		newpos = m_targetPoint;
//	}
//	if(newpos == GetPosition())
//		return;
//
//
//	GameObjectListInterface& objs = GetGameObjectManager()->GetFarRangeObjects();
//	int numObj = objs.GetCount();
//
//	CRect moveBox = *m_boundingbox;
//	moveBox.left += m_displacement.X;
//
//	for(int i=0;i<numObj;i++)
//	{
//		GameObject* obj = objs[i];
//		if(obj == this)
//			continue;
//
//		if(obj->IsEnabled() && 
//			obj->IsCollidable() && 
//			obj->GetObjectType() != Object_Room &&
//			obj->GetObjectType() != Object_Robot)
//		{
//			if(!moveBox.IsIntersect(*obj->GetBoundingBox()))
//			{
//				continue;
//			}
//			else
//			{
//				m_displacement.set(0, 0);
//				break;
//			}
//
//		}
//	}
//	
//}
//
//void Robot::TestCollisions(GameObject* obj,vector2df* resultant)
//{
//	if(obj->GetObjectType()== Object_Balloon)
//	{
//	/*	ACircle* colObjMain = (ACircle*)obj->GetCollisionAreaByName("Main");
//		ACircle* colMyHead = (ACircle*)this->GetCollisionAreaByName("Head");
//		vector2df R1R2 = colObjMain->Pos() - colMyHead->Pos();
//		if(R1R2.getLengthSQ() <= (colObjMain->Radius() + colObjMain->Radius())*(colObjMain->Radius() + colObjMain->Radius()))
//		{
//			if(resultant)
//			{
//				*resultant += R1R2;
//			}
//		}*/
//	}	
//}
void Robot::SetNoDisplacement()
{
	m_Speed.set(0, 0);
	m_displacement.set(0, 0);
	if(m_physicsBody)
		m_physicsBody->SetLinearVelocity(b2Vec2(0,0));
}

void Robot::CompDisplacement()
{
	m_displacement = m_Speed;
	
	b2Vec2 spd(m_displacement.X,m_displacement.Y);
	m_physicsBody->SetLinearVelocity( spd );
	
}